package movepaint.stateMachine;

import fr.lri.swingstates.canvas.CStateMachine;
import fr.lri.swingstates.canvas.Canvas;
import fr.lri.swingstates.sm.State;
import fr.lri.swingstates.sm.Transition;
import fr.lri.swingstates.sm.transitions.Drag;
import fr.lri.swingstates.sm.transitions.KeyPress;
import fr.lri.swingstates.sm.transitions.Press;
import fr.lri.swingstates.sm.transitions.Release;
import java.awt.BasicStroke;
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import movepaint.GestureRecognition;
import movepaint.stateMachine.InkMachine;

/**
 * Machine a état utilisée pour le mode selection/deplacement des figures
 * @author Paulino A.
 * @version 1.0
 */
public class SelectMoveMachine extends CStateMachine {
    private Canvas _canvas;                 // Référence au canvas de la frame
    private GestureRecognition _frameMain;  // Référence à la frame principale
    private Point2D _pInit;

    // Textes des astuces!!
    private final static String TIP_SELECTION_MULTIPLE = "Tip : Maintenez CTRL pour sélectionner plusieurs figures.";
    private final static String TIP_TERMINER_SEGMENT = "Tip : Relachez le clique gauche pour dessiner le segment";
    private final static String TIP_TERMINER_FIGURE  = "Tip : Clique droit pour fermer le tracé";

    public SelectMoveMachine(Canvas c, GestureRecognition frameMain) {
        super(c);
        _canvas = c;
        _frameMain = frameMain;
    }

    /**
     * Retourne le nom de la machine a état
     * @return Nom de la machine a état
     */
    public String getName() {
        return "SelectMoveMachine";
    }


    /**
     * Etat initial du mode selection/deplacement de figure
     */
    public State start = new State() {
        boolean isSelectionMultiple = false;

        // Transition pour la suppression des shapes via la touche (SUPPR)
        Transition deleteShapes = new KeyPress(KeyEvent.VK_DELETE) {

            public void action() {
                _frameMain.deleteShapes(InkMachine.TAG_SHAPE_HOVERED);
            }
        };

        // Pour la fonction selectionner/deplacer (selection multiple  (CTRL + click)
        Transition selectShapes = new PressOnTag(InkMachine.TAG_SHAPE, BUTTON1, CONTROL, ">> move") {

            public void action() {
                if (_frameMain.drawMode() == GestureRecognition.MODE_SELECT_DEPLACE) {
                    isSelectionMultiple = true;

                    // Point de départ
                    _pInit = getPoint();

                    getShape().setStroke(new BasicStroke(InkMachine.SHAPE_HOVERED));
                    getShape().addTag(InkMachine.TAG_SHAPE_HOVERED);

                    // On informe l'user d'une astuce (selection multiple)
                    _frameMain._statusBar.isWork(true);
                    _frameMain._statusBar.setStatusText(TIP_SELECTION_MULTIPLE);
                }
            }
        };

        // Pour la fonction copier
        Transition pressOnShape = new PressOnShape(BUTTON1, ">> move") {

            public void action() {
                if (_frameMain.drawMode() == GestureRecognition.MODE_SELECT_DEPLACE) {
                    if (getShape().hasTag(InkMachine.TAG_SHAPE)) {
                        // Point de départ
                        _pInit = getPoint();

                        // Pour un simple click, on ne sélectionne qu'un seul SHAPE
                        if (!getShape().hasTag(InkMachine.TAG_SHAPE_HOVERED)) {
                            resetSelectedShapes();
                        }

                        getShape().setStroke(new BasicStroke(InkMachine.SHAPE_HOVERED));
                        getShape().addTag(InkMachine.TAG_SHAPE_HOVERED);

                        // On informe l'user d'une astuce (selection multiple)
                        _frameMain._statusBar.isWork(true);
                        _frameMain._statusBar.setStatusText(TIP_SELECTION_MULTIPLE);
                    } else {
                        resetSelectedShapes();
                    }
                }
            }
        };

        // Transition qui qui correspond à un clique dans le "vide". On désélectionne
        //  les figures sélectionnées
        Transition begin = new Press(BUTTON1, ">> move") {

            public void action() {
                // Point de départ
                _pInit = getPoint();

                if (_frameMain.drawMode() == GestureRecognition.MODE_SELECT_DEPLACE) {
                    // Ici, la transition correspond a un click autre que dans une shape.
                    //  On assigne cela a une "déselection" des shapes a déplacer.
                    resetSelectedShapes();
                    isSelectionMultiple = false;
                }
            }
        };
    };

    /**
     * Statut permettant le déplacement des shapes
     */
    public State move = new State() {

        // Commence a déplacer les shapes sélectionnées
        Transition moveShape = new Drag(BUTTON1) {

            public void action() {
                if (_frameMain.drawMode() == GestureRecognition.MODE_SELECT_DEPLACE) {
                    // On calcule les dX et dY pour la translation
                    double dx = getPoint().getX() - _pInit.getX();
                    double dy = getPoint().getY() - _pInit.getY();

                    // MAJ du point
                    _pInit = getPoint();

                    // On translate
                    if (_canvas.getTag(InkMachine.TAG_SHAPE_HOVERED) != null) {
                        _canvas.getTag(InkMachine.TAG_SHAPE_HOVERED).translateBy(dx, dy);
                    }
                }
            }
        };

        /*
        Transition dragOnShape = new DragOnShape(BUTTON1) {
        public void action() {
        // En mode deplacement, on change les coordonnées de la/les shapes sélectionnées
        if (_frameMain.drawMode() == GestureRecognition.MODE_SELECT_DEPLACE){
        // On calcule les dX et dY pour la translation
        double dx = getPoint().getX() - pInit.getX();
        double dy = getPoint().getY() - pInit.getY();

        // MAJ du point
        pInit = getPoint();

        // On translate
        if (canvas.getTag(TAG_SHAPE_HOVERED) != null) {
        canvas.getTag(TAG_SHAPE_HOVERED).translateBy(dx, dy);
        }
        }
        }
        };
         */

        // Fin du déplacement
        Transition end = new Release(BUTTON1, ">> start") {

            public void action() {
                _frameMain._statusBar.isWork(false);
            }
        };
    };

    /**
     * Supprime les tags des shapes sélectionnées
     *  ET enleve leurs surlignements.
     */
    private void resetSelectedShapes() {
        if (_canvas.getTag(InkMachine.TAG_SHAPE_HOVERED) != null) {
            _canvas.getTag(InkMachine.TAG_SHAPE_HOVERED).setStroke(new BasicStroke(InkMachine.SHAPE_NOT_HOVERED));
        }
        _canvas.removeTag(InkMachine.TAG_SHAPE_HOVERED);
    }
}
